/**
*****************************************************************************************
*     Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
*****************************************************************************************
* @file     fast_prov_client.h
* @brief    Head file for fast provision client
* @details
* @author   hector_huang
* @date     2020-07-15
* @version  v1.0
* *************************************************************************************
*/

#ifndef _FAST_PROV_CLIENT_H_
#define _FAST_PROV_CLIENT_H_

#include "platform_types.h"
#include "profile_client.h"

BEGIN_DECLS

/** @addtogroup Fast_Prov_Client
  * @{
  */

/**
 * @defgroup Fast_Prov_Client_Exported_Macros Exported Macros
 * @{
 */
#define FAST_PROV_CLIENT_MAX_DATA_OUT_LEN       32
/** @} */

/**
 * @defgroup Fast_Prov_Client_Exported_types Exported Types
 * @{
 */
/**  fast provision client ID. */
extern T_CLIENT_ID fast_prov_client_id;

typedef enum
{
    HDL_FAST_PROV_SRV_START,
    HDL_FAST_PROV_SRV_END,
    HDL_FAST_PROV_DATA_IN,
    HDL_FAST_PROV_DATA_OUT,
    HDL_FAST_PROV_DATA_OUT_END,
    HDL_FAST_PROV_DATA_OUT_CCCD,
    HDL_FAST_PROV_CACHE_LEN
} fast_prov_handle_type_t;

typedef enum
{
    FAST_PROV_DISC_DONE,
    FAST_PROV_DISC_FAIL,
    FAST_PROV_DISC_NOT_FOUND
} fast_prov_disc_state_t;

typedef struct
{
    fast_prov_handle_type_t handle_type;
    uint16_t handle_value;
} fast_prov_disc_hdl_info_t;

typedef enum
{
    FAST_PROV_READ_DATA_OUT_CCCD,
    FAST_PROV_READ_DATA_OUT
} fast_prov_read_type_t;

typedef struct
{
    uint16_t len;
    uint8_t fast_prov_data_out[FAST_PROV_CLIENT_MAX_DATA_OUT_LEN];
} _PACKED_ fast_prov_data_out_value_t;

typedef union
{
    bool fast_prov_data_out_cccd;
    fast_prov_data_out_value_t value;
} fast_prov_read_data_t;

typedef struct
{
    fast_prov_read_type_t type;
    fast_prov_read_data_t data;
    uint16_t cause;
} fast_prov_read_result_t;

typedef enum
{
    FAST_PROV_WRITE_DATA_IN
} fast_prov_write_type_t;

typedef struct
{
    fast_prov_write_type_t type;
    uint16_t cause;
} fast_prov_write_result_t;

typedef enum
{
    FAST_PROV_DATA_OUT_NOTIFY
} fast_prov_notify_indicate_type_t;

typedef struct
{
    fast_prov_notify_indicate_type_t type;
    fast_prov_data_out_value_t value;
} fast_prov_notify_indicate_data_t;

typedef enum
{
    FAST_PROV_CLIENT_CB_TYPE_DISC_STATE,          //!< Discovery procedure state, done or pending.
    FAST_PROV_CLIENT_CB_TYPE_READ_RESULT,         //!< Read request's result data, responsed from server.
    FAST_PROV_CLIENT_CB_TYPE_WRITE_RESULT,        //!< Write request result, success or fail.
    FAST_PROV_CLIENT_CB_TYPE_NOTIF_IND_RESULT,    //!< Notification or indication data received from server.
    FAST_PROV_CLIENT_CB_TYPE_INVALID              //!< Invalid callback type, no practical usage.
} fast_prov_client_cb_type_t;

typedef union
{
    fast_prov_disc_state_t disc_state;
    fast_prov_disc_hdl_info_t disc_hdl_info;
    fast_prov_read_result_t read_result;
    fast_prov_write_result_t write_result;
    fast_prov_notify_indicate_data_t notify_indicate_data;
} fast_prov_client_cb_content_t;

typedef struct
{
    fast_prov_client_cb_type_t cb_type;
    fast_prov_client_cb_content_t cb_content;
} fast_prov_client_cb_data_t;
/** @} */

/**
 * @defgroup Fast_Prov_Client_Exported_Functions Exported Functions
 * @{
 */

/**
 * @brief add fast provision client to gatt stack
 * @param[in] app_cb: application callback function
 * @return service id
 */
T_CLIENT_ID fast_prov_client_add(P_FUN_GENERAL_APP_CB app_cb);

/**
 * @brief start discovery fast provision service
 * @param[in] conn_id: connection link id
 * @retval TRUE: start discovery success
 * @retval FALSE: start discovery fail
 */
bool fast_prov_client_start_discovery(uint8_t conn_id);

/**
 * @brief read data from server by using handles.
 * @param[in] conn_id: connection link id
 * @param[in] type: one of characteristic that has the readable property.
 * @retval TRUE: send request to upper stack success.
 * @retval FALSE: send request to upper stack failed.
 */
bool fast_prov_client_read_by_handle(uint8_t conn_id, fast_prov_read_type_t type);

/**
 * @brief read data from server by using uuids.
 * @param[in] conn_id: connection link id
 * @param[in] type: one of characteristic that has the readable property.
 * @retval TRUE: send request to upper stack success.
 *         FALSE: send request to upper stack failed.
 */
bool fast_prov_client_read_by_uuid(uint8_t conn_id, fast_prov_read_type_t type);

/**
 * @brief enable or disable the notification of peer server's notify characteristic.
 * @param[in] conn_id: connection link id
 * @param[in] command: 0-disable the notification, 1-enable the notification.
 * @retval TRUE: send request to upper stack success.
 * @retval FALSE: send request to upper stack failed.
 */
bool fast_prov_client_data_out_cccd_set(uint8_t conn_id, bool command);

/**
 * @brief send write request to peer server's control point characteristic.
 * @param[in] conn_id: connection link id
 * @param[in] pdata: data to write
 * @param[in] length: data length
 * @retval TRUE: send request to upper stack success.
 * @retval FALSE: send request to upper stack failed.
 */
bool fast_prov_client_data_in_write(uint8_t conn_id, uint8_t *pdata, uint16_t length);

/**
 * @brief enable or diable fast provision mode
 * @param[in] enable: TRUE enable, FALSE disable
 * @retval TRUE: send request to upper stack success.
 * @retval FALSE: send request to upper stack failed.
 */
bool fast_prov_client_fast_prov_enable(uint8_t conn_id, bool enable);

/**
 * @brief set network key
 * @param[in] conn_id: connection link id
 * @param[in] key_refresh_flag: network key refresh flag
 * @param[in] net_key_index: network key index
 * @param[in] net_key: network key
 * @retval TRUE: send request to upper stack success.
 * @retval FALSE: send request to upper stack failed.
 */
bool fast_prov_client_set_net_key(uint8_t conn_id, uint8_t key_refresh_flag, uint16_t net_key_index,
                                  uint8_t net_key[16]);

/**
 * @brief set application key
 * @param[in] conn_id: connection link id
 * @param[in] app_key_index: application network key index
 * @param[in] app_key: application key
 * @retval TRUE: send request to upper stack success.
 * @retval FALSE: send request to upper stack failed.
 */
bool fast_prov_client_set_app_key(uint8_t conn_id, uint16_t app_key_index, uint8_t app_key[16]);

/**
 * @brief set iv index
 * @param[in] conn_id: connection link id
 * @param[in] iv_update_flag: iv update flag
 * @param[in] iv_index: iv index
 * @retval TRUE: send request to upper stack success.
 * @retval FALSE: send request to upper stack failed.
 */
bool fast_prov_client_set_iv_index(uint8_t conn_id, uint8_t iv_update_flag, uint32_t iv_index);

/**
 * @brief set device unicast address and key
 * @param[in] conn_id: connection link id
 * @param[in] unicast addr: device unicast address
 * @param[in] dev_key: device key
 * @retval TRUE: send request to upper stack success.
 * @retval FALSE: send request to upper stack failed.
 */
bool fast_prov_client_set_dev_addr_key(uint8_t conn_id, uint16_t unicast_addr, uint8_t dev_key[16]);

/**
 * @brief  used by application, to set the handles in fast_prov handle cache.
 * @param[in] type: handle types of this specific profile.
 * @param[in] value: handle value to set.
 * @retval TRUE: success.
 * @retval FALSE: failed.
 */
bool fast_prov_client_handle_set(fast_prov_handle_type_t type, uint16_t value);

/**
 * @brief  used by application, to get the handles in fast_prov handle cache.
 * @param[in] type: handle types of this specific profile.
 * @retval handle value.
 */
uint16_t fast_prov_client_handle_get(fast_prov_handle_type_t type);

/** @} */
/** @} */

END_DECLS

#endif /** _FAST_PROV_CLIENT_H_ */

